package com.lishe.lishe.retrofit.MyRequestBody;

import com.lishe.lishe.retrofit.BaseRequestBody;
import com.lishe.lishe.retrofit.MyObserver.FileUploadObserver;
import com.lishe.lishe.retrofit.bean.UploadInfo;

import java.io.File;
import java.io.IOException;

import io.reactivex.annotations.Nullable;
import okhttp3.MediaType;
import okhttp3.RequestBody;
import okio.Buffer;
import okio.BufferedSink;
import okio.ForwardingSink;
import okio.Okio;
import okio.Sink;
import okio.Timeout;

/**
 * Created by DELL on 2017/11/22.
 */

public class UploadFileRequestBody extends RequestBody {

    private RequestBody mRequestBody;
    private FileUploadObserver<BaseRequestBody<UploadInfo>> fileUploadObserver;

    public UploadFileRequestBody(File file,FileUploadObserver<BaseRequestBody<UploadInfo>> fileUploadObserver){
        this.mRequestBody=RequestBody.create(MediaType.parse("application/octet-stream"),file);
        this.fileUploadObserver=fileUploadObserver;
    }

    public UploadFileRequestBody(byte[] buff,FileUploadObserver<BaseRequestBody<UploadInfo>> fileUploadObserver){
        this.mRequestBody=RequestBody.create(MediaType.parse("multipart/form-data"),buff);
        this.fileUploadObserver=fileUploadObserver;
    }

    @Nullable
    @Override
    public MediaType contentType() {
        return mRequestBody.contentType();
    }

    @Override
    public long contentLength() throws IOException {
        return mRequestBody.contentLength();
    }

    @Override
    public void writeTo(BufferedSink sink) throws IOException {
        CountingSink countingSink=new CountingSink(sink);
        BufferedSink bufferedSink= Okio.buffer(countingSink);
        //写入
        mRequestBody.writeTo(bufferedSink);
        //必须调用flush，否则最后一部分数据可能不会被写入
        bufferedSink.flush();
    }

    protected final class CountingSink extends ForwardingSink{

        private long bytesWritten=0;
        public CountingSink(Sink delegate) {
            super(delegate);
        }

        @Override
        public void write(Buffer source, long byteCount) throws IOException {
            super.write(source, byteCount);

            bytesWritten+=byteCount;
            if(fileUploadObserver!=null){
                fileUploadObserver.onProgressChange(bytesWritten,contentLength());
            }
        }

        @Override
        public Timeout timeout() {
            fileUploadObserver.onError(new Throwable("connect timeout!"));
            return super.timeout();
        }
    }
}
